#include "Truck.h"

Truck::Truck( Printer &prt, NameServer &nameServer, BottlingPlant &plant,
		unsigned int numVendingMachines, unsigned int maxStockPerFlavour )
	: myPrinter(prt), myNameServer(nameServer), myPlant(plant),
		myNumVendingMachines(numVendingMachines), 
		myMaxStockPerFlavour(maxStockPerFlavour)
{
    myCargo = new unsigned int[VendingMachine::FLAVOUR_SIZE]();		
    for(unsigned int i = 0; i < VendingMachine::FLAVOUR_SIZE; i++)
    {
        myCargo[i] = 0;
    }	
}

Truck::~Truck()
{
	delete[] myCargo;
}

void Truck::main()
{
	// starting
	myPrinter.print(Printer::Truck, 'S');
	VendingMachine**	delivery_list = myNameServer.getMachineList();
	
	while(true)
	{
		unsigned int resting_time = Global::prng(1, 10);
		yield(resting_time);
		
		bool plant_closing = myPlant.getShipment(myCargo);
		if(plant_closing) break;
		
		int total_shipment = 0; // count the number of items
		for(int i=0; i<VendingMachine::FLAVOUR_SIZE; i++)
		{
			total_shipment += myCargo[i];
		}
		myPrinter.print(Printer::Truck, 'P', total_shipment);

		for(unsigned int i=0; i<myNumVendingMachines; i++)
		{	
			myPrinter.print(Printer::Truck, 'd', i, total_shipment);

			// get the number of cans that this machine has
			unsigned int* VM_inventory = delivery_list[i]->inventory();

			int total_unsatisfied = 0;	// the unfilled number of cans
			for(int j=0; j<VendingMachine::FLAVOUR_SIZE; j++)
			{
				// Get the number of cans that the vending maching is 
				// expecting
				unsigned int num_cans_to_fill = myMaxStockPerFlavour - 
												VM_inventory[j]; 
				// if the machine want more than what we have, cap it
				if(num_cans_to_fill > myCargo[j])
				{
					total_unsatisfied += num_cans_to_fill - myCargo[j];
					num_cans_to_fill = myCargo[j];
				}

				total_shipment -= num_cans_to_fill;
				myCargo[j] -= num_cans_to_fill;
				VM_inventory[j] += num_cans_to_fill;
			} //for Floavour Size

			if(total_unsatisfied > 0)
			{
				myPrinter.print(Printer::Truck, 'U', i,total_unsatisfied);
			}

			// notify that the machine is now ready to go
			delivery_list[i]->restocked();
			myPrinter.print(Printer::Truck, 'D', i, total_shipment);

			// if cargo has run out, then not need to go to then next
			// vending  machine, simply return.
			if(total_shipment <= 0) break;
		} // for each vending machine
	} // while(true)

	myPrinter.print(Printer::Truck, 'F');
}
